#include <jni.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include<android/log.h>


#define TAG "TOUCH-JNI" // 这个是自定义的LOG的标识
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__)

jint readFlag = 0;
jint writeFlag = 0;


extern "C" {
    JNIEXPORT jbyteArray JNICALL
    Java_com_example_zh_1idreader_rc522ReadFromJNI(
            JNIEnv* env,
            jobject /* this */) {
    }


/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidOpenDevice
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidOpenDevice
  (JNIEnv *, jobject) {
            char path[30] = "/dev/rc522";
            int fd = 0;
        fd = open(path, O_RDWR);
        if (fd < 0) {
            LOGE("Open file failed");
            return -1;
        }
        ioctl(fd, 1, 0);
        close(fd);
        return 1;
  }

/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidCloseDevice
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidCloseDevice
  (JNIEnv *, jobject) {
  readFlag = 0;
            char path[30] = "/dev/rc522";
            int fd = 0;
        fd = open(path, O_RDWR);
        if (fd < 0) {
            LOGE("Open file failed");
            return -1;
        }
        ioctl(fd, 0, 0);
        close(fd);
        return 1;
  }

/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidReadEnable
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidReadEnable
  (JNIEnv *, jobject) {
            char path[30] = "/dev/rc522";
            int fd = 0;
        fd = open(path, O_RDWR);
        if (fd < 0) {
            LOGE("Open file failed");
            return -1;
        }
        ioctl(fd, 4, 1);
        close(fd);
    return 1;
  }

/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidReadDisable
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidReadDisable
  (JNIEnv *, jobject) {
            char path[30] = "/dev/rc522";
            int fd = 0;
        fd = open(path, O_RDWR);
        if (fd < 0) {
            LOGE("Open file failed");
            return -1;
        }
        ioctl(fd, 4, 0);
        close(fd);
    return 1;
    }

/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidReadEnable
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidReadContinuityEnable
        (JNIEnv *, jobject) {
    char path[30] = "/dev/rc522";
    int fd = 0;
    fd = open(path, O_RDWR);
    if (fd < 0) {
        LOGE("Open file failed");
        return -1;
    }
    ioctl(fd, 5, 1);
    close(fd);
    return 1;

}

/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidReadDisable
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidReadContinuityDisable
        (JNIEnv *, jobject) {
    char path[30] = "/dev/rc522";
    int fd = 0;
    fd = open(path, O_RDWR);
    if (fd < 0) {
        LOGE("Open file failed");
        return -1;
    }
    ioctl(fd, 5, 0);
    close(fd);
    return 1;

}

/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidSetKeyAndMode
 * Signature: ([I)I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidSetKeyAndMode
  (JNIEnv *env, jobject, jintArray buf) {
    jint* arr = env->GetIntArrayElements(buf,NULL);
    jint length = env->GetArrayLength(buf);
    jbyte byteArr[length];
    for(int i=0; i < length; i++) {
        byteArr[i] = arr[i];
    }
            char path[30] = "/dev/rc522";
            int fd = 0;
        fd = open(path, O_WRONLY, 0);
        if (fd < 0) {
            LOGE("Open file failed");
            return -1;
        }
        write(fd, byteArr, length);
        close(fd);
    return 1;
  }

/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidSetSecNumAndBlockNum
 * Signature: ([I)I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidSetSecNumAndBlockNum
  (JNIEnv *env, jobject, jintArray buf) {
    jint* arr = env->GetIntArrayElements(buf,NULL);
    jint length = env->GetArrayLength(buf);
    jbyte byteArr[length];
    for(int i=0; i < length; i++) {
        byteArr[i] = arr[i];
    }
            char path[30] = "/dev/rc522";
            int fd = 0;
        fd = open(path, O_WRONLY, 0);
        if (fd < 0) {
            LOGE("Open file failed");
            return -1;
        }
        write(fd, byteArr, length);
        close(fd);
    return 1;
                                  }

/*
 * Class:     com_example_zh_idreader_IDReader
 * Method:    RfidReadCardIDSecAndBlock
 * Signature: ([I)I
 */
JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidReadCardIDSecAndBlock
  (JNIEnv *env, jobject, jintArray retArray) {
        jint length = env->GetArrayLength(retArray);
            char path[30] = "/dev/rc522";
            int fd = 0, len = 0, i, ret = 0;
        fd = open(path, O_RDWR);
        if (fd < 0) {
            LOGE("Open file failed");
            return -1;
        }
        readFlag = 1;
        jbyte buf[26];
        jint arr[26];
        do {
            usleep(200000);
            len = read(fd, buf, 26);
            if(len>0) {
                for(i=0; i<length; i++) {
                    arr[i] = buf[i];
                }
                env->SetIntArrayRegion(retArray, 0, length, arr);
                env->ReleaseIntArrayElements(retArray, arr, JNI_COMMIT);
                ret = 1;
                break;
            }
        } while(readFlag);
        close(fd);
                                    return ret;
               }


JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidWriteCardIDSecAndBlock
  (JNIEnv *env, jobject, jintArray buf) {
    jint* arr = env->GetIntArrayElements(buf,NULL);
    jint length = env->GetArrayLength(buf);
    jbyte byteArr[length];
    for(int i=0; i < length; i++) {
        byteArr[i] = arr[i];
    }
            char path[30] = "/dev/rc522";
            int fd = 0, len = 0, i;
        fd = open(path, O_RDWR);
        if (fd < 0) {
            LOGE("Open file failed");
            return -1;
        }
        ioctl(fd, 1, 0);
        writeFlag = 1;
        do {
            len = write(fd, byteArr, 17);
            LOGD("Write len: %d", len);
            if(len == -1) {
                return -1;
            }
            if(len>0) {
                return 1;
            }
            usleep(200000);
        } while(writeFlag);
        close(fd);
        return 0;

  }


JNIEXPORT jint JNICALL Java_com_example_zh_1idreader_IDReader_RfidStopWriteCardIDSecAndBlock
  (JNIEnv *, jobject) {
        writeFlag = 0;
        return 1;
  }
}